//
//  test_graph.cpp
//  cobalt
//
//  Created by Nicolas Godbout on 2013-09-03.
//  Copyright (c) 2013 Nicolas Godbout. All rights reserved.
//

// #include "test_graph.h"

#include "../cobalt/rdf/environment.h"
#include "../cobalt/vocabulary.h"
#include "../cobalt/parse_nt.h"
#undef FAIL
#undef TEST
#include "gtest/gtest.h"

namespace rdf {
    class GraphTest : public ::testing::Test {
    protected:
        static Environment *env;
        static Graph graphBase;
        
        Graph graph;
        
        GraphTest() {}
        virtual ~GraphTest() {}
        
        virtual void SetUp() {
            graph = graphBase;
        }
        virtual void TearDown() {
            graph = Graph();
        }

        static void SetUpTestCase() {
            env = new Environment();
            ParseNT parser(env);
            parser.parse(
                         R"nt(
                         <resource1> <property> <resource2> .
                         _:anon <property> <resource2> .
                         <resource7> <property> "simple literal" .
                         )nt");
            graphBase = parser.getGraph();
        }
        
        static void TearDownTestCase() {
            delete env;
        }
        
    };
    
    Environment* GraphTest::env;
    Graph GraphTest::graphBase {};

    TEST_F(GraphTest, ParseTestGraph) {
        EXPECT_EQ(3, graph.length());
    }
    
    TEST_F(GraphTest, NoAddEmptyTriple) {
        EXPECT_THROW(graph.add(Triple()), std::invalid_argument) ;
    }
    
    TEST_F(GraphTest, MatchMethod) {
        // match subject named node
        Graph res = graph.match(env->createNamedNode("resource1"),
                                RDFNode(),
                                RDFNode());
        EXPECT_EQ(1, res.length());
        
        // match predicate named node
        res = graph.match(RDFNode(),
                          env->createNamedNode("property"),
                          RDFNode());
        EXPECT_EQ(3, res.length());
        
        // match object named node
        res = graph.match(RDFNode(),
                          RDFNode(),
                          env->createNamedNode("resource2"));
        EXPECT_EQ(2, res.length());
        
        // match object literal
        res = graph.match(RDFNode(),
                          RDFNode(),
                          env->createLiteral("simple literal", vocab::xsd::string));
        EXPECT_EQ(1, res.length());
        
        // match subject/predicate
        res = graph.match(env->createNamedNode("resource1"),
                          env->createNamedNode("property"),
                          RDFNode());
        EXPECT_EQ(1, res.length());
        
        // match subject/predicate/object
        res = graph.match(env->createNamedNode("resource1"),
                          env->createNamedNode("property"),
                          env->createNamedNode("resource2"));
        EXPECT_EQ(1, res.length());
        
        // match predicate/object
        res = graph.match(RDFNode(),
                          env->createNamedNode("property"),
                          env->createLiteral("simple literal", vocab::xsd::string));
        EXPECT_EQ(1, res.length());
    }
}